package com.hzjh.base.web.process

import android.os.Handler
import android.os.Looper
import android.util.ArrayMap
import android.util.Log
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ProcessUtils
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.hzjh.base.web.IBridgeInvokeMainProcess
import com.hzjh.base.web.IBridgeInvokeWebProcess
import com.hzjh.base.web.util.WebLog

class BridgeCommandHandler : IBridgeInvokeMainProcess.Stub() {
    //客户端注册的监听事件 只需监听一个
//    private val receiveListeners =  RemoteCallbackList<IBridgeInvokeWebProcess>()
    private var receiveListener:IBridgeInvokeWebProcess?=null
    companion object {
        private const val TAG = "ProcessBridge"

        @Volatile
        private var sInstance: BridgeCommandHandler? = null

        fun getInstance(): BridgeCommandHandler {
            if (sInstance == null) {
                synchronized(this) {
                    if (sInstance == null) {
                        WebLog.d(
                            TAG,
                            "初始化 当前进程：${ProcessUtils.getCurrentProcessName()}"
                        )
                        sInstance = BridgeCommandHandler()
                    }
                }
            }
            return sInstance!!
        }
    }

    // 用于切线程
    private val mHandle = Handler(Looper.getMainLooper())

    private val mCommandMap: ArrayMap<String, IBridgeCommand> by lazy { BridgeUtil.autoRegist() }

    // 暴露给外部方法 分发调用
    override fun handleBridgeInvoke(command: String?, params: String?, bridgeCallback: IBridgeInvokeWebProcess?) {
        WebLog.d(TAG, "handleBridgeInvoke() 当前进程：${ProcessUtils.getCurrentProcessName()}")
        // map 中存在命令 则执行
        if (mCommandMap.contains(command)) {
            mHandle.post { // 切换到主线程 获取命令 执行
                mCommandMap[command]!!.exec(parseParams(params), bridgeCallback)
            }
        } else {
            Log.e(TAG, "handleBridgeInvoke() command[${command}] is not register!")
        }
    }

    override fun registerReceiveListener(listener: IBridgeInvokeWebProcess?) {
//        receiveListeners.register(listener)
        receiveListener=listener
    }

    override fun unregisterReceiveListener(listener: IBridgeInvokeWebProcess?) {
//        val success = receiveListeners.unregister(listener)
//        if (success) {
//            LogUtils.d(TAG, "解除注册成功")
//        } else {
//            LogUtils.d(TAG, "解除注册失败")
//        }
        receiveListener=null
    }

    override fun getValueForKey(key: String?): String {
        WebLog.d(TAG, "getValueForKey() 当前进程：${ProcessUtils.getCurrentProcessName()}")
       return ValueForKeyBridge.exec(key)
    }

    //主进程向web进程发送消息
    fun sendCommand(message: BridgeMessage?) {
        WebLog.d(TAG, "主进程->web进程发送消息 sendCommand() message: $message")
        if (checkMessage(message)) {
            // 校验命令通过后 执行命令
            excuteCommand(message)
        }
    }
    //主进程向web进程发送消息
    fun sendValueForKey(key: String?): String {
        WebLog.d(TAG, "主进程->web进程发送消息 sendValueForKey() key: $key")
        try {
            return receiveListener?.getValueForKey(key)?:""
        }catch(e :Exception){
            Log.e(TAG,e.toString())
        }
        return ""
    }


    // 校验命令、参数 合法性
    private fun checkMessage(message: BridgeMessage?): Boolean {
        if (message == null) {
            WebLog.d(TAG, "send() jsBridgeParam is null")
            return false
        }
        if (message.name.isNullOrEmpty()) {
            WebLog.d(TAG, "send() jsBridgeParam.name is null")
            return false
        }
        return true
    }

    //执行命令
    private fun excuteCommand(message: BridgeMessage?) {
        try {
//            val n = receiveListeners.beginBroadcast()
//            for (i in 0 until n) {
//                val listener = receiveListeners.getBroadcastItem(i)
//                listener?.handleBridgeCallback(message?.name, message?.data?.toJson())
//            }
//            receiveListeners.finishBroadcast()
            receiveListener?.handleBridgeCallback(message?.name,Gson().toJson(message?.data))
        }catch(e :Exception){
            Log.e(TAG,e.toString())
        }
    }

    private fun parseParams(params: String?): JsonObject? {
        if (params.isNullOrEmpty()) {
            return null
        }
        return GsonUtils.fromJson(params, JsonObject::class.java)
    }

}